#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project ：NoBad 
@File    ：view.py
@Author  ：LYP
@Date    ：2025/10/30 13:26 
@description :
"""
import json
import os

from django.db.models import Q
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework import status
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiParameter
from django.shortcuts import get_object_or_404
from models.models import PromptTemplate, TemplateImage, ReportTemplate, ImageTemplateConfig
from tool.permissions import IsTokenValid
from tool.tools import CustomStatus, logger
from tool.base_views import BaseViewSet
from tool.uploader_data import upload_image_to_cos
from tool.utils import CustomPagination, ApiResponse
from django.utils.translation import gettext as _

class PromptTemplateSerializer(serializers.ModelSerializer):
    """
    提示词序列化器
    """

    class Meta:
        model = PromptTemplate
        fields = '__all__'
        read_only_fields = ('created_time', 'updated_time')

    def validate_name(self, value):
        """
        验证提示词名称不能为空
        """
        if not value.strip():
            raise serializers.ValidationError(_("提示词名称不能为空"))
        return value

    def validate_content(self, value):
        """
        验证提示词内容不能为空
        """
        if not value.strip():
            raise serializers.ValidationError(_("提示词内容不能为空"))
        try:
            print(value)
            json.loads(value)
        except json.JSONDecodeError:
            pass
        return value


@extend_schema(tags=["提示词管理"])
@extend_schema_view(
    list=extend_schema(
        summary="获取提示词列表",
        description="返回所有提示词的信息列表",
        responses={200: PromptTemplateSerializer(many=True)},
        parameters=[
            OpenApiParameter(name="name", description="提示词名称", required=False),
        ]
    ),
    create=extend_schema(
        summary="创建提示词",
        description="创建一个新的提示词",
        request=PromptTemplateSerializer,
        responses={201: PromptTemplateSerializer},
    )
)
class PromptListView(BaseViewSet):
    """
    提示词列表视图 - 处理提示词的增删改查
    """
    pagination_class = CustomPagination
    # permission_classes = [IsTokenValid]
    serializer_class = PromptTemplateSerializer

    def get_queryset(self):
        # 获取查询参数
        name = self.request.GET.get('name', None)

        # 构建查询条件
        queryset = PromptTemplate.objects.filter(~Q(template_type__contains="_"))
        if name:
            queryset = queryset.filter(name__icontains=name)

        return queryset

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            # 使用自定义分页响应
            return self.get_paginated_response(serializer.data)
        # 如果没有分页，返回普通响应
        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(serializer.data)

    def get_serializer_class(self):
        return PromptTemplateSerializer

    def post(self, request):
        """
        创建提示词
        """
        try:
            logger.info("创建提示词")
            logger.info(request.data)
            serializer = PromptTemplateSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(
                    CustomStatus.CREATED.to_response(data=serializer.data),
                    status=status.HTTP_201_CREATED
                )
            else:
                return Response(
                    CustomStatus.VALIDATION_ERROR.to_response(data=serializer.errors),
                    status=status.HTTP_400_BAD_REQUEST
                )
        except Exception as e:
            logger.error(f"创建提示词失败: {str(e)}")
            return Response(
                CustomStatus.INTERNAL_ERROR.to_response(),
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


@extend_schema(tags=["提示词管理"])
@extend_schema_view(
    get=extend_schema(
        summary="获取提示词详情",
        description="根据提示词ID获取单个提示词的详细信息",
        responses={200: PromptTemplateSerializer}
    ),
    put=extend_schema(
        summary="更新提示词",
        description="根据提示词ID更新提示词信息",
        request=PromptTemplateSerializer,
        responses={200: PromptTemplateSerializer}
    ),
    delete=extend_schema(
        summary="删除提示词",
        description="根据提示词ID删除提示词",
        responses={204: _("删除成功")}
    )
)
class PromptDetailView(BaseViewSet):
    """
    提示词详情视图
    """

    def get(self, request, pk):
        """
        获取提示词详情
        """
        try:
            prompt = get_object_or_404(PromptTemplate, pk=pk)
            serializer = PromptTemplateSerializer(prompt)
            return Response(
                CustomStatus.SUCCESS.to_response(data=serializer.data)
            )
        except PromptTemplate.DoesNotExist:
            return Response(
                CustomStatus.NOT_FOUND.to_response(),
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"获取提示词详情失败: {str(e)}")
            return Response(
                CustomStatus.INTERNAL_ERROR.to_response(),
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def put(self, request, pk):
        """
        更新提示词
        """
        try:
            prompt = get_object_or_404(PromptTemplate, pk=pk)
            serializer = PromptTemplateSerializer(prompt, data=request.data)
            if serializer.is_valid():
                serializer.save()
                return Response(
                    CustomStatus.UPDATED.to_response(data=serializer.data)
                )
            else:
                return Response(
                    CustomStatus.VALIDATION_ERROR.to_response(data=serializer.errors),
                    status=status.HTTP_400_BAD_REQUEST
                )
        except PromptTemplate.DoesNotExist:
            return Response(
                CustomStatus.NOT_FOUND.to_response(),
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"更新提示词失败: {str(e)}")
            return Response(
                CustomStatus.INTERNAL_ERROR.to_response(),
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def delete(self, request, pk):
        """
        删除提示词
        """
        try:
            prompt = get_object_or_404(PromptTemplate, pk=pk)
            prompt.delete()
            return Response(
                CustomStatus.DELETED.to_response()
            )
        except PromptTemplate.DoesNotExist:
            return Response(
                CustomStatus.NOT_FOUND.to_response(),
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"删除提示词失败: {str(e)}")
            return Response(
                CustomStatus.INTERNAL_ERROR.to_response(),
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )


class TemplateImageSerializer(serializers.ModelSerializer):
    """
    模板图片序列化器
    """

    class Meta:
        model = TemplateImage
        fields = "__all__"


class ReportTemplateSerializer(serializers.ModelSerializer):
    """
    报告模板序列化器
    """
    images_detail = TemplateImageSerializer(source='images', many=True, read_only=True)
    # 用于接收图片ID列表
    image_ids = serializers.ListField(
        child=serializers.IntegerField(),
        write_only=True,
        required=False,
        help_text=_("图片ID列表")
    )
    name = serializers.CharField(required=False)
    template_type = serializers.CharField(required=False)
    template_purpose = serializers.CharField(required=False)
    min_score = serializers.IntegerField(required=False)
    max_score = serializers.IntegerField(required=False)
    template_belong = serializers.CharField(required=False)

    class Meta:
        model = ReportTemplate
        fields = ['id', 'images_detail', 'name', 'template_type', 'template_purpose', 'gender', 'is_active',
                  'min_score', 'max_score', 'template_belong', 'created_time', 'image_ids']
        read_only_fields = ('created_time',)

    def create(self, validated_data):
        image_ids = validated_data.pop('image_ids', [])
        report_template = ReportTemplate.objects.create(**validated_data)
        if image_ids:
            images = TemplateImage.objects.filter(id__in=image_ids)
            report_template.images.set(images)
        return report_template

    def update(self, instance, validated_data):
        image_ids = validated_data.pop('image_ids', None)
        # 更新其他字段
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        # 更新图片关联
        if image_ids is not None:
            images = TemplateImage.objects.filter(id__in=image_ids)
            instance.images.set(images)

        return instance


@extend_schema(tags=["报告模板管理"])
@extend_schema_view(
    list=extend_schema(
        summary="获取报告模板列表",
        description="返回所有报告模板的信息列表",
        responses={200: ReportTemplateSerializer(many=True)},
        parameters=[
            OpenApiParameter(name="name", description="模板名称", required=False),
            OpenApiParameter(name="template_type", description="模板类型", required=False),
            OpenApiParameter(name="template_purpose", description="模板用途", required=False),
            OpenApiParameter(name="is_active", description="是否启用", required=False, type=bool),
        ]
    ),
    create=extend_schema(
        summary="创建报告模板",
        description="创建一个新的报告模板，可关联多个图片",
        request=ReportTemplateSerializer,
        responses={201: ReportTemplateSerializer},
    ),
    retrieve=extend_schema(
        summary="获取报告模板详情",
        description="根据报告模板ID获取单个报告模板的详细信息",
        responses={200: ReportTemplateSerializer}
    ),
    update=extend_schema(
        summary="更新报告模板",
        description="根据报告模板ID更新报告模板信息",
        request=ReportTemplateSerializer,
        responses={200: ReportTemplateSerializer}
    ),
    destroy=extend_schema(
        summary="删除报告模板",
        description="根据报告模板ID删除报告模板",
        responses={204: "删除成功"}
    )
)
class ReportTemplateView(BaseViewSet):
    """
    报告模板视图集 - 处理报告模板的增删改查
    """
    serializer_class = ReportTemplateSerializer
    pagination_class = CustomPagination
    queryset = ReportTemplate.objects.all()

    def get_queryset(self):
        """
        重写get_queryset方法，根据查询参数进行过滤
        """
        queryset = super().get_queryset()

        # 获取查询参数
        name = self.request.query_params.get('name')
        template_type = self.request.query_params.get('template_type')
        template_purpose = self.request.query_params.get('template_purpose')
        is_active = self.request.query_params.get('is_active')

        # 应用过滤条件
        if name:
            queryset = queryset.filter(name__icontains=name)
        if template_type:
            queryset = queryset.filter(template_type=template_type)
        if template_purpose:
            queryset = queryset.filter(template_purpose=template_purpose)
        if is_active is not None:
            is_active = is_active.lower() in ['true', '1', 'yes']
            queryset = queryset.filter(is_active=is_active)

        return queryset

    def list(self, request, *args, **kwargs):
        """
        获取报告模板列表
        """
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(serializer.data)

    def create(self, request, *args, **kwargs):
        """
        创建报告模板
        """
        try:
            serializer = self.get_serializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                return ApiResponse(
                    data=serializer.data,
                    message=_("创建成功"),
                    code=201
                )
            else:
                return ApiResponse(
                    data=serializer.errors,
                    message=_("数据验证失败"),
                    code=400
                )
        except Exception as e:
            logger.error(_("创建报告模板失败"), str(e))
            return ApiResponse(
                data={},
                message=_("创建失败 %s") % str(e),
                code=500
            )

    def retrieve(self, request, *args, **kwargs):
        """
        获取报告模板详情
        """
        try:
            instance = self.get_object()
            serializer = self.get_serializer(instance)
            return ApiResponse(serializer.data)
        except ReportTemplate.DoesNotExist:
            return ApiResponse(
                data={},
                message=_("报告模板不存在"),
                code=404
            )
        except Exception as e:
            logger.error(f"获取报告模板详情失败: {str(e)}")
            return ApiResponse(
                data={},
                message=_("获取详情失败: %s") % str(e),
                code=500
            )

    def update(self, request, *args, **kwargs):
        """
        更新报告模板
        """
        try:
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data, partial=False)
            if serializer.is_valid():
                serializer.save()
                return ApiResponse(
                    data=serializer.data,
                    message=_("更新成功")
                )
            else:
                return ApiResponse(
                    data=serializer.errors,
                    message=_("数据验证失败"),
                    code=400
                )
        except ReportTemplate.DoesNotExist:
            return ApiResponse(
                data={},
                message=_("报告模板不存在"),
                code=404
            )
        except Exception as e:
            logger.error(f"更新报告模板失败: {str(e)}")
            return ApiResponse(
                data={},
                message=(_("更新失败: "),{str(e)}),
                code=500
            )

    def destroy(self, request, *args, **kwargs):
        """
        删除报告模板
        """
        try:
            instance = self.get_object()
            instance.delete()
            return ApiResponse(
                data={},
                message=_("删除成功")
            )
        except ReportTemplate.DoesNotExist:
            return ApiResponse(
                data={},
                message=_("报告模板不存在"),
                code=404
            )
        except Exception as e:
            logger.error(f"删除报告模板失败: {str(e)}")
            return ApiResponse(
                data={},
                message=(_("删除失败: "),str(e)),
                code=500
            )


@extend_schema(tags=["模板图片管理"])
@extend_schema_view(
    list=extend_schema(
        summary="获取模板图片列表",
        description="返回所有模板图片的信息列表",
        responses={200: TemplateImageSerializer(many=True)},
        parameters=[
            OpenApiParameter(name="name", description="图片名称", required=False),
        ]
    ),
    create=extend_schema(
        summary="批量上传模板图片",
        description="支持上传多个图片文件，文件名格式为 yymmddhhmmss_index.ext",
        request={
            'multipart/form-data': {
                'type': 'object',
                'properties': {
                    'files': {
                        'type': 'array',
                        'items': {'type': 'string', 'format': 'binary'},
                        'description': '要上传的图片文件列表'
                    }
                },
                'required': ['files']
            }
        },
        responses={
            200: {
                'description': '上传成功',
                'content': {
                    'application/json': {
                        'schema': {
                            'type': 'object',
                            'properties': {
                                'code': {'type': 'integer', 'example': 200},
                                'message': {'type': 'string'},
                                'data': {
                                    'type': 'object',
                                    'properties': {
                                        'success_count': {'type': 'integer'},
                                        'failed_count': {'type': 'integer'},
                                        'saved_images': {
                                            'type': 'array',
                                            'items': {
                                                'type': 'object',
                                                'properties': {
                                                    'id': {'type': 'integer'},
                                                    'name': {'type': 'string'},
                                                    'url': {'type': 'string'}
                                                }
                                            }
                                        },
                                        'failed_uploads': {
                                            'type': 'array',
                                            'items': {
                                                'type': 'object',
                                                'properties': {
                                                    'name': {'type': 'string'},
                                                    'reason': {'type': 'string'}
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    )
)
class TemplateImageView(BaseViewSet):
    """
    模板图片视图
    """
    serializer_class = TemplateImageSerializer
    pagination_class = CustomPagination
    queryset = TemplateImage.objects.all()

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            # 使用自定义分页响应
            return self.get_paginated_response(serializer.data)
        # 如果没有分页，返回普通响应
        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(serializer.data)

    def create(self, request, *args, **kwargs):
        """
        批量上传模板图片
        支持上传多个图片文件，文件名格式为 yymmddhhmmss.png
        """
        try:
            from datetime import datetime

            # 获取所有上传的文件
            uploaded_files = request.FILES.getlist('files')
            if not uploaded_files:
                return ApiResponse(
                    data={},
                    message=_("未找到上传文件"),
                    code=400
                )
            saved_images = []
            failed_uploads = []
            for i, uploaded_file in enumerate(uploaded_files):
                try:
                    # 生成文件名：yymmddhhmmss.png
                    timestamp = datetime.now().strftime('%y%m%d%H%M%S')
                    ext = os.path.splitext(uploaded_file.name)[1] or '.png'
                    file_name = f"{timestamp}_{i}{ext}"
                    full_file_name = f"template_images/{file_name}"
                    # 读取文件内容
                    file_content = uploaded_file.read()
                    # 上传到COS
                    upload_result = upload_image_to_cos(file_content, full_file_name)
                    if upload_result:
                        # 保存到数据库
                        template_image = TemplateImage.objects.create(
                            name=file_name,
                            image_url=upload_result['url']
                        )
                        saved_images.append({
                            'id': template_image.id,
                            'name': template_image.name,
                            'url': template_image.image_url
                        })
                    else:
                        failed_uploads.append({
                            'name': uploaded_file.name,
                            'reason': _('上传失败')
                        })

                except Exception as e:
                    failed_uploads.append({
                        'name': uploaded_file.name,
                        'reason': str(e)
                    })
            message = _("批量上传完成：成功 {0} 个，失败 {1} 个").format(len(saved_images), len(failed_uploads))
            return ApiResponse(
                data={
                    'success_count': len(saved_images),
                    'failed_count': len(failed_uploads),
                    'saved_images': saved_images,
                    'failed_uploads': failed_uploads
                },
                message=message
            )

        except Exception as e:
            logger.error(f"批量上传模板图片失败: {str(e)}")
            message = _("上传过程中发生错误:%s") % str(e)
            return ApiResponse(
                data={},
                message=message,
                code=500
            )


class ImageTemplateConfigSerializer(serializers.ModelSerializer):
    """
    图片模板配置序列化器
    """

    class Meta:
        model = ImageTemplateConfig
        fields = '__all__'


@extend_schema(tags=["背景图片位置配置"])
@extend_schema_view(
    list=extend_schema(
        summary="获取背景图片位置列表",
        description="返回所有背景图片位置的信息列表",
        responses={200: ImageTemplateConfigSerializer(many=True)},
    ),
    create=extend_schema(
        summary="创建背景图片位置",
        description="创建一个新的背景图片位置，可关联多个图片",
        request=ImageTemplateConfigSerializer,
        responses={201: ReportTemplateSerializer},
    ),
    retrieve=extend_schema(
        summary="获取背景图片位置详情",
        description="根据背景图片位置ID获取单个背景图片位置的详细信息",
        responses={200: ImageTemplateConfigSerializer}
    ),
    update=extend_schema(
        summary="更新背景图片位置",
        description="根据背景图片位置ID更新背景图片位置信息",
        request=ImageTemplateConfigSerializer,
        responses={200: ImageTemplateConfigSerializer}
    ),
    destroy=extend_schema(
        summary="删除背景图片位置",
        description="根据背景图片位置ID删除背景图片位置",
        responses={204: "删除成功"}
    )
)
class BackImagePostionConfigView(BaseViewSet):
    """
    图片模板配置视图
    """
    serializer_class = ImageTemplateConfigSerializer
    pagination_class = CustomPagination
    queryset = ImageTemplateConfig.objects.all()
